import 'package:cherrilog/cherrilog.dart';
import 'package:cherrilog/model/message.dart';
import 'package:logger/logger.dart';

abstract class LogAdapter {
  void e(
    dynamic message, {
    DateTime? time,
    Object? error,
    StackTrace? stackTrace,
  });

  void w(
    dynamic message, {
    DateTime? time,
    Object? error,
    StackTrace? stackTrace,
  });

  void i(
    dynamic message, {
    DateTime? time,
    Object? error,
    StackTrace? stackTrace,
  });

  void d(
    dynamic message, {
    DateTime? time,
    Object? error,
    StackTrace? stackTrace,
  });

  void f(
    dynamic message, {
    DateTime? time,
    Object? error,
    StackTrace? stackTrace,
  });
}

class LoggerAdapter implements LogAdapter {
  final Logger logger;

  LoggerAdapter(this.logger);

  @override
  void d(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.d(message, time: time, error: error, stackTrace: stackTrace);

  @override
  void e(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.e(message, time: time, error: error, stackTrace: stackTrace);

  @override
  void i(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.i(message, time: time, error: error, stackTrace: stackTrace);

  void log(Level level, message,
          {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.log(level, message,
          time: time, error: error, stackTrace: stackTrace);

  @override
  void w(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.w(message, time: time, error: error, stackTrace: stackTrace);

  @override
  void f(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.f(message, time: time, error: error, stackTrace: stackTrace);

  void t(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.t(message, time: time, error: error, stackTrace: stackTrace);

  Future<void> close() => logger.close();
}

class CherriLoggerAdapter implements LogAdapter {
  final CherriLog logger;

  CherriLoggerAdapter(this.logger);

  @override
  void d(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.log(CherriMessage(
        CherriLogLevel.debug,
        message,
        time ?? DateTime.now(),
        stackTrace: stackTrace,
      ));

  @override
  void e(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.log(CherriMessage(
        CherriLogLevel.error,
        message,
        time ?? DateTime.now(),
        stackTrace: stackTrace,
      ));

  @override
  void i(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.log(CherriMessage(
        CherriLogLevel.info,
        message,
        time ?? DateTime.now(),
        stackTrace: stackTrace,
      ));

  @override
  void w(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.log(CherriMessage(
        CherriLogLevel.warning,
        message,
        time ?? DateTime.now(),
        stackTrace: stackTrace,
      ));

  @override
  void f(message, {DateTime? time, Object? error, StackTrace? stackTrace}) =>
      logger.log(CherriMessage(
        CherriLogLevel.fatal,
        message,
        time ?? DateTime.now(),
        stackTrace: stackTrace,
      ));
}
